home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-09-16 | 50.9 KB | 1,730 lines |
-
- Eric's Pascal Utilities / EPasUtil
- Copyright 1986 by Eric W. Wedaa
- 4620 E. 17th St
- Tucson AZ, 85711
- BIX: EWedaa
- CIS: 76515.2274
- ALL rights reserved.
-
- Personal Pascal copyright 1985 by Optimized Systems Software, Inc.
-
- FOR PERSONAL PASCAL VERSIONS 1.XX
-
- This is a Shareware program. It is distributed freely in the
- hopes that you will find it to be of some use to you while
- programming in OSS Personal Pascal 1.XX. It is NOT to be
- distributed by any of the "Pay for a Public Domain disk" companies
- that exist. It may be distributed freely over any BBS or computer
- service such as Compuserve or BIX.
-
- If you find this program to be of use to you, feel free to
- send me a check for my time and effort. ($25.00 recomended.)
- Please include the version number and where you obtained the
- program from. Program updates will be posted as they are written
- and when people inform me of bugs or problems in the program. If
- this program does not work with your version of Pascal, send me a
- note, and I'll see what I can do about it.
-
- Partial source code to this program has been placed in the
- Public Domain as EROUTINE.ARC (Eric's Routines in archived
- format.) If you use these routines, I would appreciate it if you
- could send me a disk (Single of Double sided) with some of your
- Pascal routines, and any Public Domain software that you have.
- Please include my name in the opening credits of any program that
- uses these routines.
-
- Thank you,
-
- Eric W. Wedaa.
-
-
-
-
-
-
- What is Eric's Pascal Utilities?
- ====================================================
-
- Eric's Pascal Utilities is a collection of handy utilities
-
- that I've designed to help write Pascal programs. Most of these
-
- are adaptations of various utilities that are available for
-
- programmers on other machines that I've grown used to. When I
-
- started writing code on my ST at home, I realized how dependent I
-
- had become on them to write code. Since they were not available,
-
- I decided to write them myself.
-
-
- Who's Eric's Pascal Utilities for anyways?
- ====================================================
-
- Well, if you program in Pascal, then this program is for you.
-
- But lets make sure of who you are. Hopefully, you're familiar
-
- with the Atari ST and how it works. I also hope that you aren't a
-
- beginning Pascal programmer anymore. This program is most useful
-
- to people writing programs that are over a hundred or so lines
-
- long.
-
-
- By the way, you should be a person who cares enough about
-
- programming to want to write cleaner, as well as more stylish, and
-
- more efficient code. That, I can help you with. As you go
-
- through this article, I'll be pointing out how to best use the
-
- routines to write better code. But it's still up to you to use
-
- what the program tells you.
-
-
- The following chart presents a brief overview of the routines
-
- available to in Eric's Pascal Utilities. This is mainly intended
-
- for those of you who will just skim the article, and then move on
-
- to explore on your own. I know that's what I do 99% of the time.
-
- If you intend on reading the article straight through, and then
-
- using the program, you can skip this section.
-
-
- --Listing Files: This routine prints out a source code file
- to the printer. Along the way to the printer, it
- adds the line number that the Compiler and the
- Cross Reference routine uses.
-
- --Showing Files: The same as above, but to the screen
- instead. Extremely helpful for deciding where to
- start your Listing.
-
- --Procedure I/O: Sends a listing of all your routines, in
- the order declared to a text file called ".PRO".
- It includes all the parameters associated with the
- routine, as well as the line number it's declared
- on.
-
- --Cross Reference: A sorted listing of all your identifiers,
- what they are, and their block level declared and
- used. If you choose the Full Cross Reference
- option, You'll get a text file longer than your
- program file. But it's extremely handy.
-
- --Fix Capitalization: This routine goes through your source
- code and changes all of your capitalization. You
- have eight word sets, and four choices of
- capitalization styles to choose from.
-
- --Format: Basically, all it does is make a "Pretty Print"
- test file with the "FRM" or a "PRN" extension. Go
- read the section on it in detail.
-
- --Statistics: A quick run down on how often you use a
- given word in your program.
-
-
- What's on the disk
- ====================================================
-
- There are 4 files on this disk. They fall into three
-
- categories, EPASUTIL Program files, Documentation files, and
-
- Sample Program files. They are:
-
-
- 2 Program files
- --EPASUTIL.PRG. The program.
- --EPASUTIL.DAT. The program's data file.
-
- 1 Documentation files.
- --READ.ME. Last minute notes and corrections.
- --EPASUTIL.DOC Program documentation
-
-
- Starting up.
- ====================================================
-
- O.K. You've double-clicked the EPASUTIL.PRG icon or the file
-
- name. Now what? Well, after the program has loaded and started
-
- running, you will get a message saying "Please Wait, Loading
-
- data." Loading the data will take a couple of seconds.
-
-
- After that's done, the screen will clear, and the title
-
- screen will appear. Hit the Return key and you will then see the
-
- Main dialog box. This is where you will choose options.
-
-
- To choose an option, just point and click on the button you
-
- want. After you do that, the screen will clear, and the GEM File
-
- Selector box will appear. If you choose the CANCEL button, you
-
- will be returned to the Main dialog box. If you choose a valid
-
- file name, you will move on to the rest of that routine.
-
-
- Listing Files
- ====================================================
-
-
- This routine will print out your program file with the
-
- Compiler and Cross Reference line numbers printed in front of each
-
- line. Any line longer than 73 characters long will have the
-
- remaining part(s) indented and printed on the line below it.
-
-
- The beauty of this really shows when you have just compiled
-
- a program, and have received several error messages. Instead of
-
- plowing through your source code by hand, you can just refer to
-
- the latest listing, and go directly to the line number. This way,
-
- you can see the whole routine where the error is, and what the
-
- full effects of that error are.
-
-
- You can also go through all of your source code at one time
-
- tracking down the identifiers that are listed with the cross
-
- reference routine. This way you can see where you messed up in
-
- your declarations, and make the corrections on your print out
-
- before going in with the editor to make the corrections.
-
-
- This method of tracking down identifiers is faster than
-
- plowing through with the editor trying to track down all the
-
- changes. With all the corrections listed on your print out in the
-
- order that they happen, you can just go straight through the file,
-
- instead of jumping around from section to section. You also won't
-
- have to worry about changing line counts, since you will be able
-
- to what lines are before and after your identifier.
-
-
- When you have a print out from this routine, you can keep it
-
- current by having a few blank lines in your original source code.
-
- This way, when you do add a line, you can add it from one of blank
-
- lines. Doing this will keep your line numbers valid for a longer
-
- length of time. You can then easily track down your run-time
-
- errors, since your print out will still have valid line numbers
-
- for most of the code.
-
-
- The box sequence for this routine is as follows:
-
- --GEM File Selector box.
- --Start/End dialog box.
-
-
- The Start-End dialog box will ask you for the line number or
-
- routine name that you want the listing to start at, and the line
-
- number or routine name that you want it to finish at. When you
-
- are done entering this information, hit the "DONE" button to start
-
- the listing.
-
-
- If you enter a blank line as the starting word, then the
-
- listing will start from the beginning of the file. Entering a
-
- blank line as the ending word will cause the listing to continue
-
- to the end of the file.
-
-
- If you enter a valid line number or routine name (One that
-
- actually exists.) there will be a short delay before the print out
-
- starts. If you enter a line number that is larger than your
-
- program, or a routine name that does not exist, then it will read
-
- through the file looking for it, and will return you to the Main
-
- dialog box when it reaches the end of the file.
-
-
- If you have entered a valid line number or routine name as
-
- the end word, the listing will stop printing when it reaches that
-
- line number or name. If it doesn't find that line number or name,
-
- it will print all of the file from the starting point.
-
-
- It should be noted that this program is set up for reasonable
-
- Pascal source code. If you start having lines longer than 210
-
- characters, the last line won't be properly indented. (Just
-
- thought you'd like to know.)
-
-
- Showing files
- ====================================================
-
- This routine acts almost exactly like the List routine. The
-
- differences are that it sends the display to the screen, and that
-
- it ignores the "END AT" option in the Start/End dialog box.
-
-
- This routine is used to track down a starting and ending
-
- position for the other routines. If you aren't sure of where you
-
- want to start a listing or a cross referencing, you can just start
-
- looking from the beginning of the file. This way you can save
-
- time and paper when you list or cross reference your file. You can
-
- also save time in the cross reference routine by just referencing
-
- the routines you want.
-
-
- For the details on using this routine, go to the List
-
- section of this article. This routine will display the file to
-
- the screen 19 lines at a time. At the bottom of each screen you
-
- will see the prompt "More?". Entering in a "N", "n", or a
-
- CONTROL C, will abort the listing. Any other key will show you
-
- the next page.
-
-
- One thing to be noted again is that the "End at" prompt in
-
- the dialog box will be ignored. You can go ahead and enter
-
- something, but it will be up to you to end the listing by a "N",
-
- "n", or a CONTROL C.
-
-
- Fixing Capitalization
- ====================================================
-
- This routine goes through a file and fix the capitalization
-
- style on eight sets of words, with four options of capitalization
-
- for each word set.
-
-
- You would use this when your file is already indented and
-
- formatted in a specific way, and you don't want to use the Format
-
- routine to reformat the program.
-
-
- This routine is helpful for making the different types of
-
- words jump out of your listings. For example, you can choose all
-
- the Pascal words to be converted into lower case, and your words
-
- to be in upper case. This way, when you look at your listing,
-
- your identifiers will jump off the screen or listing at you.
-
-
- The sequence for this routine is as follows:
-
- --GEM File Selector dialog box.
-
- --Pascal Reserved Words dialog box.
- --Pascal Constants dialog box.
- --Pascal Types dialog box.
- --Pascal Routines dialog box.
- --GEM Routines dialog box.
- --GEM Types dialog box.
- --GEM Constants dialog box.
- --Your Words dialog box.
-
-
- Each of Word dialog boxes will have the name of the word set
-
- at the top, and then four buttons describing how you want that
-
- word set to be capitalized. Hitting any of the buttons will end
-
- that dialog box, and move you to the next one.
-
-
- The routine will start after you have entered the capitaliz-
-
- ation option for Your Words. The routine will read in your file,
-
- make the corrections, and then write it out to another file with a
-
- ".CAP" extension.
-
-
- It should be noted here that if you are redefining a Pascal
-
- or GEM word, that it will still be capitalized as the original
-
- word type. This routine isn't smart enough to pay attention to
-
- what words you have redefined.
-
-
- The high point of all of that is when you use this routine,
-
- the new listing will point out which words you have used that
-
- could have another meaning. For example, define all your words to
-
- be in lower case, and all the other words to be something else.
-
- Any word that you use that is a GEM or Pascal word will be
-
- capitalized in something other that lower case.
-
-
- The eight word sets are:
-
- --Pascal Reserved Words. (For, Do, Case, While, Repeat, etc.)
-
- --Pascal Constants. (True, False, Maxint, etc.)
-
- --Pascal Types. (Char, Text, Integer, String, etc.)
-
- --Pascal Routines. (Writeln, Reset, etc.)
-
- --GEM Routines. (Do_Dialog, Get_in_file, Draw_String, etc.)
-
- --GEM Types. ( Str255, Dialog_ptr, M_Bee, etc.)
-
- --GEM Constants. (Selected, None, Selectable, etc.)
-
- --Your Words. (Any words that you use that aren't inside of a
- comment or string, and aren't one of the above.
- That is, X, Y, Your_Choice are your words, but
- Writeln( even if you redeclare it), 'This is a
- literal', and {This is a comment.} aren't.)
-
-
- The capitalization options are:
-
- --All Capitals. (From Roger_Wilco to ROGER_WILCO.)
- (From ROGER_WilcO to ROGER_WILCO.)
- (From roger_wilco to ROGER_WILCO.)
-
- --All Lower Case. (From Roger_Wilco to roger_wilco.)
- (From ROGER_WILCO to roger_wilco.)
- (From roger_wilco to roger_wilco.)
-
- --First Letter Caps. (From Roger_Wilco to Roger_Wilco.)
- (From ROGER_WILCO to Roger_Wilco.)
- (From Roger_wilcO to Roger_Wilco.)
-
- --Original. (From Roger_Wilco to Roger_Wilco.)
- (From RoGER_WilcO to RoGER_WilcO.)
- (From roger_wilco to roger_wilco.)
-
-
- Cross Referencing Identifiers
- ====================================================
-
- The Cross Reference routine goes through your source code,
-
- and creates a text file telling you about your variables. The
-
- SHORT form, which is best for saving storage space creates a
-
- sorted list of each identifier, where it was used, and a one
-
- letter descriptor of that use. The FULL form lists out the the
-
- file on a line by line description of which identifiers you are
-
- using and where they were declared.
-
-
- A good Cross Reference routine can save hours, if not days
-
- of trouble shooting, as well as save a few K here and there. I'd
-
- rather not think about the times that I've accidentally messed
-
- everything up by using a global variable and thinking that it was
-
- local instead. You can also easily track down every occurrence of
-
- a variable to see where it's being changed, and which one of those
-
- changes is the one that's messing your program up.
-
-
- You can also see which identifiers are being used only once,
-
- and you can delete them from your source code, or use them. (As
-
- you see fit.)
-
-
- This routine also comes in handy if you like to steal/salvage
-
- /re-use code from other programs. If you tend to import the
-
- majority of a routine, and all of it's declarations, this will
-
- come in handy. After you have imported and modified the code,
-
- there are almost always some identifiers declared, but not used in
-
- the routine.
-
-
- Instead of going through it by hand, you can just run it
-
- through this routine. Everytime an identifier is declared, it
-
- starts a new line in the print out. So, just by looking at the
-
- print out, your unused identifiers will jump off the page at you.
-
- Then you can go and delete them from your source code file.
-
-
- An example of this is as follows:
-
-
- 1) Word 1234:V1 1241=v1 1243:v1
- 2) 1276:V1
- 3) 1350:V1 1360=v1
-
-
- We have declared "Word" on lines 1234, 1276, and 1350 of the
-
- program. But, it appears that it is never being used in the
-
- routine that includes line 1276. This situation is definitely
-
- worth looking into. It's very possible that you could delete that
-
- declaration without causing any harm to the program at all.
-
-
- Another thing to note about the above sample is lines 1350
-
- and 1360. You have it declared at 1350, and modified at 1360.
-
- (The = sign shows us that it's being modified.) Now why would we
-
- want to just set a variable to something and never use it's value?
-
- It's probable that you're just initializing it to some value and
-
- never using it. (A common waste of time and space.) This is
-
- something that possibly could be deleted from the program.
-
-
- Another good use is for when you have nested routines. If
-
- you declared an identifier in your main routine and then declare
-
- it again in a sub-routine, this routine will point that out to
-
- you. That's because everytime you declare an identifier, it
-
- starts a new line in the file. So what happens is you will see
-
- the identifier listed once as declared, and then a new line, with
-
- it listed as declared again. It will look something like this:
-
-
- 1) Word 1234:V1 1241:v1 1243:v1
- 2) 1276:V1
- 3) 1280:V2 1283:v2 1296:v2 1301:v2
- 4) 1350:v1 1360:v1
-
-
- Where line 1 above is a normal use of the variable. Line 2
-
- is another declaration of the variable. In line 3 we have it
-
- declared and used in a nested routine. Line 4 is where we start
-
- using the variable we declared on line 2. In this instance, you
-
- would go and look at those lines to see if you really need to have
-
- it declared again. True, the program may run just as well if it's
-
- redeclared, but it's not as nice.
-
-
- The sequence for this routine is as follows:
-
- --GEM File Selector dialog box.
-
- --Start/End dialog box.
- --Cross Reference Mode alert box.
- --Routines Only alert box.
- --Reference Include Files alert box.
-
- The Start/End dialog box is here to determine which sections
-
- of code should be cross referenced. This box follows the same
-
- general rules as listed in the Listing section. The routine will
-
- go through your program keeping track of which identifiers are
-
- declared where, but will only create the file when it reaches the
-
- start position. You would use this when you want to cross
-
- reference certain sections of your program.
-
-
- The Cross Reference Mode alert box is to determine whether
-
- you want the FULL or SHORT Cross Reference modes. The SHORT Mode
-
- will just print out the name of the identifier, the line number
-
- that it is on, a one character identifier description, and the
-
- level that it is being used.
-
-
- The FULL Mode of the Cross Reference utility shows the above
-
- information, but is preceded by a line by line use of the varia-
-
- bles. In this case, it goes routine by routine, listing in order
-
- where you declared and where you used certain identifiers. This
-
- comes in really handy for making sure that you are only using
-
- global identifiers where you should be.
-
-
- The Routines Only alert box is for when you just want to
-
- track down where your routines are declared and used. It gives
-
- almost the same output as cross referencing all your identifiers,
-
- except that it will only print out your routine information.
-
-
- The Reference Include Files alert box is so you can Cross
-
- Reference the INCLUDE files that your programs uses. If you
-
- choose this option, everytime the program finds an INCLUDE file
-
- declared, it will pause the program and ask you to locate the
-
- Include file. If you enter a valid file name, the Cross
-
- Referencer will open that file and cross reference it as well. It
-
- will start a new line number everytime it includes another file,
-
- and will return to the old line number when it resumes Cross
-
- Referencing the main program file. (It should be stated that the
-
- program will only recognize a "{$I" command when it is the first
-
- three characters on the line.)
-
-
- The Used/Modified characters are as follows:
-
- --':' This variable is being used or accessed.
-
- --'=' This variable is being modified on this line.
-
-
- The one letter characters are as follows:
-
-
- --C: This identifier was declared as a constant.
-
- --T: This identifier was declared as a type.
-
- --F: This function was declared on this line.
-
- --f: This function was called on this line.
-
- --P: This procedure was declared on this line.
-
- --p: This procedure was called on this line.
-
- --G: This Global identifier was declared on this line.
-
- --g: This global identifier was used on this line.
-
- --V: This identifier was declared locally on this line.
-
- --v: This identifier was used locally on this line.
-
- --R: The procedure was called recursively from itself on this
- line.
-
- --?: You haven't declared it yet.
-
-
- A couple of notes on the current version.
-
- --It is set up for a maximum of 1000 global identifiers.
- --This version will only work to four levels of nested
- routines, not counting the global level.
- --All routines are stored in their own area of memory, and
- are treated as if they were declared globally.
-
- Formatting Pascal Source code
- ====================================================
-
- Well, this is the tricky part of the program. This routine
-
- will take your Pascal source code, and format it (or pretty print,
-
- if you prefer that term) for you. This is probably one of the
-
- best things you can do for your source code since it becomes much
-
- more readable. And when it's easily readable, it's easily
-
- fixable and changeable.
-
-
- When you have formatted code, tracking down bugs becomes much
-
- easier than tracking them down in "Messy" looking code. It also
-
- just looks nicer too. It's sort of like a car. Doesn't it feel
-
- better to drive a car when it's clean, rather than when it's
-
- dirty? It's the same way with source code. Clean looking code is
-
- just so much easier to work with than sloppy code.
-
-
- The way I and many others write code, is just plain messy.
-
- I'm always in too much of a hurry to really bother with writing
-
- clean code the first time through it. I'd much rather write it,
-
- than make it look nice. I never get the BEGIN/END pairs lined up
-
- correctly, my IF/THEN/ELSE statements are always ugly looking, and
-
- my capitalization is NEVER consistent. I take my car to the
-
- car wash, and now I can do the same thing with my programs. And
-
- the end result is code that's a lot nicer to work on.
-
-
- "Well", you ask, "What else is pretty code good for?" A lot,
-
- it turns out. Nice looking code that follows the same format
-
- rules throughout is a lot easier to debug and modify than sloppy
-
- code, or code that isn't indented consistently. With formatted
-
- code, you can make sure that statements are on the correct side of
-
- your BEGIN statements or your END statements. It will also
-
- visually show you which routines are nested, as well as what
-
- routines they are nested in. Formatted code can also make complex
-
- IF/THEN/ELSE statements extremely clear.
-
-
- The sequence for this routine is as follows:
-
- --GEM File Selector dialog box.
-
- --Defaults alert box.
- --Print or Compile alert box.
-
- --Tabbing dialog box.
-
- Capitalization dialog boxes.
- --Pascal Reserved Words dialog box.
- --Pascal Constants dialog box.
- --Pascal Types dialog box.
- --Pascal Routines dialog box.
- --GEM Routines dialog box.
- --GEM Types dialog box.
- --GEM Constants dialog box.
- --Your Words dialog box.
-
- --Returns dialog box #1.
- --Returns dialog box #2.
-
-
- After you've picked the file you want formatted, the program
-
- will ask you if you want to accept the default values or not.
-
- (These are listed in appendix 1.) If you don't choose the default
-
- option, then you will go through a series of alert and dialog
-
- boxes where you can pick out your own particular formatting rules.
-
-
- After you choose whether or not to accept the defaults, you
-
- will move on to the Print/Compile alert box. If you choose the
-
- Print option, your source code will be formatted for the printer.
-
- The file extension for the Print option is ".PRN" and for the
-
- compile option it is ".FRM".
-
-
- The Compile option will format your code according to your
-
- rules, the same as the Print option. But for lines that are longer
-
- than 80 columns, it will slide those left to column one. If they
-
- are still longer than 80 columns, the line number will be printed
-
- to an ".ERR" file, so you can look at them next time you use the
-
- editor.
-
-
- What the Print Option does is insert a "|" between your
-
- BEGIN/END sets and your REPEAT/UNTIL sets. Also, a "*" will be
-
- printed in front of your nested routines to point them out. And
-
- lastly, each line will be printed with ALL of the proper
-
- indentations, instead of having lines longer than 80 columns slid
-
- over to the left as is done with the Compile option.
-
-
- If you've decided to set up your own rules for indentation,
-
- carriage returns, and capitalization, you'll move on to those
-
- dialog boxes. If you haven't, (you've accepted the defaults) then
-
- the program will start formatting your code.
-
-
- The first dialog box you will come to is the indents or
-
- Tabbing dialog box. This is where you choose how many blanks you
-
- want in front of each line. This is only set up for a maximum of
-
- 256 indents. Any more than that, and your on your own. Of
-
- course, 256 indents, at 1 space each is 256 characters, so your in
-
- deep trouble anyways.
-
-
- The next series of dialog boxes are the Capitalization
-
- options. These are the same boxes that are described in the
-
- Capitalization routine. Instead of repeating myself again for a
-
- few pages, I'll just refer you back to that section for the
-
- details on them.
-
-
- After the Capitalization options comes the two Return dialog
-
- boxes. Each box has five options, with a YES and a NO button for
-
- each. Actually, only the first one deals with returns. The other
-
- is general program clean up. These two boxes are where you can
-
- either add, or clean up a lot of garbage to your program. I'll
-
- discuss how each option can be misused as it's described.
-
-
- The first box deals specifically with adding Returns. The
-
- first option is whether or not to add a Return after each Label,
-
- Const, Type, and Var statement. If you say no, then the first
-
- identifier after each declaration will be on the same line as the
-
- declaration. If you say yes, then there will be a Return after
-
- each statement. Doing this will make your routine declarations
-
- more spread out, and a little easier to read.
-
-
- The next two options deal with Returns before and after
-
- commas. Some people like a Return before their commas, some like
-
- it after their commas. If you choose both (Yes and Yes) then
-
- every comma in your program will be on it's own line. This winds
-
- up looking silly. If you want to leave your Comma-Returns the way
-
- they are, enter a No for both of them, and a Yes for the "Preserve
-
- Comma Returns in the next dialog box.
-
-
- The next two options deal with Returns before and after
-
- AND and OR statements. Some people like a Return before their
-
- AND's, some like Returns before their OR's. If you choose both
-
- (Yes and Yes) then every AND and OR in your program will be
-
- started on it's own line.
-
-
- It's a good idea to have at least one of the options as a
-
- yes. If you say No to both options, then you have decided to get
-
- some VERY long lines in your program. What will happen is that
-
- the program will keep putting them all on one line until it
-
- reaches the DO, THEN or ELSE statement, or it reaches 255
-
- characters. (At this point, it stops formatting, and tells you
-
- that you've made a mistake. Look up the .ERR file to find out
-
- where.)
-
-
- The second dialog box deals with general housecleaning in
-
- your program. The first option is whether or not you want to
-
- preserve your existing Comma-Returns. (That is, a comma,
-
- immediately followed by a Return.)
-
-
- Choosing Yes is usually a good idea here. This way, you'll
-
- keep your routine calls and your identifier declarations spread
-
- out. If you choose No, then the routine will follow your rules
-
- for Comma Returns from the previous dialog box. If you choose No
-
- for this option, and No for the two comma options above, you'll
-
- get all of your identifiers on one line. Which may or may not be
-
- what you want. You have been warned.
-
-
- The second option is whether or not you want the program to
-
- strip all the blank lines from your program. In this case, a
-
- blank line is one that is either just a Return, or spaces and a
-
- Return.
-
-
- The third option in the box is to determine if you want to
-
- preserve your Math Return statements. ( '+', '-', '*', '/' or '='
-
- followed by a RETURN.) If you say Yes, then the formatter will
-
- keep each of those Returns in your program. If you say no, then
-
- the formatter will possibly give you some very long math formulas.
-
- (Which you shouldn't have in the first place!)
-
-
- The fourth option is whether or not you want the program to
-
- add a Return before each BEGIN statement. If you say Yes, then
-
- every BEGIN will be on it's own line. If you say No, then the
-
- only time a BEGIN will have a Return before it is when it follows
-
- a semicolon.
-
-
- The last option is whether or not you want the program to add
-
- a Form Feed (Control L) before each routine. This is mainly for
-
- when you will be printing out the file directly, and want each
-
- routine on it's own page.
-
-
- While the code is being formatted, there are certain rules
-
- that will be followed for adding spaces and Returns inside your
-
- program. Certain characters (",", "(", ")" and others), and
-
- certain character sets ("BEGIN", "END", ":=", "<=", and others)
-
- will have certain spacing and return rules enforced on them.
-
-
-
- Procedure I/O
- ====================================================
-
-
- This routine will go through your source code and create a
-
- file of all the routines, and their parameters.
-
-
- With this listing you will have a handy table of which
-
- parameters are and aren't variable, their order, and the order in
-
- which you have declared your routines. This is useful when
-
- calling a routine and you aren't sure of what the parameters are,
-
- you can just look at your printout, instead of searching for the
-
- declaration with your editor. This is also useful when you are
-
- trying to convert string value parameters into variable
-
- parameters. It will show you exactly where you need to make
-
- changes. (Strings take forever to pass as values!)
-
-
- The only dialog box in this routine is the GEM file selector
-
- box. The resulting file will have a ".PRO" extension.
-
-
- Statistics
- ====================================================
-
-
- This routine will go through your source code and write out
-
- each occurrence of any word that you tell it to find.
-
-
- The first routine is mainly for tracking down where you use
-
- certain Pascal or GEM words. This would be mainly for looking for
-
- sections that might be improved by making them into a routine.
-
- For instance, you might want to track down all of your RESET
-
- statements to see if they are similar enough to warrant being made
-
- into a routine. With this routine, it's no problem to get a
-
- quick listing of all the occurrences.
-
-
- --GEM file selector box.
- --Look for what word dialog box.
-
-
- The Word Find routine will ask you for a word. It will then
-
- go through your file looking for that word. Everytime that word
-
- is located, it will write out the line number of the occurrence to
-
- a file with a ".WRD" extender.
-
-
-
- Leaving
- ====================================================
-
- This is the easiest part of the whole program. Among the
-
- options you see at the Main dialog box, you will see the "QUIT"
-
- button. Just click the mouse in there, and away you go, straight
-
- back to the desktop. Fun, Huh?
-
-
- Technical Info
- ====================================================
-
- General Program Information
-
- I started working on the program last summer, (July 19, 1986)
-
- and I've been working on it ever since. Now I know this sounds
-
- like a long time, mainly because it is. However, it just started
-
- out as a formatter for my programs. As I wrote or imported
-
- routines for the formatter, I started adding other goodies to it.
-
- The most notable is the cross reference function. (I mean, hey, I
-
- already had most of the subroutines I would need so why not?)
-
- And things were added here and there as I discussed the program
-
- with other people. Overall, I've probably between 500 and 600
-
- hours writing and debugging.
-
-
- In writing this program I've also discovered several errors
-
- in OSS Pascal. The first main error was with the way Version 1.00
-
- of the compiler handled large arrays of information. This turned
-
- out to be a real pain to track down and I finally wound up calling
-
- OSS about it. It turns out that the early versions of the
-
- compiler would randomly eat the contents of large arrays. So I
-
- was losing the contents of my reserved word list. This was fixed
-
- in later releases, but if you try to compile the program under an
-
- early release, you might have problems. (So call up OSS and get
-
- the upgrade.)
-
-
- I also discovered a problem with the linker. I'm not sure
-
- why, but it seems that when you have a large number of routines in
-
- a module the linker flips out. In my particular case, a set of
-
- routines in the module were not returning any valid values from
-
- the routine. It was as if the whole routine was just a BEGIN/END
-
- statement without any code between them. This was solved by
-
- putting the offending routines back into the main program file.
-
-
- It also turns out that the manual doesn't give any details on
-
- how to call a dialog box without any editable fields. The call
-
- requires you to pass a pointer to the editable field. If you pass
-
- it a pointer to button or display line, it bombs the program.
-
- After posting several notices on assorted boards, I finally got
-
- the answer. It turns out you just have to pass it a 0 (zero) as
-
- the editable field parameter.
-
-
- Data File Information
-
-
- The Data file (EPASUTIL.DAT) is a simple text file. The
-
- first half of the file is the word list for the program. These
-
- are the various Pascal and GEM words that OSS Pascal uses. I
-
- obtained the various GEM and Pascal words out of the various
-
- Pascal include files and the manual. Each word set consists of a
-
- single digit, a Return, the word, and another Return. The digit
-
- describes what kind of word follows. (See appendix 2.)
-
-
- The second half of the program are the contents of assorted
-
- alert boxes. These are read into two arrays PFILEERR (Pascal
-
- error) and TFILEERR (TOS error). When an error occurs, I just
-
- use the error number as the index for the appropriate array.
-
-
- Support Modules
-
-
- The assorted "Fast Read" routines were written because they
-
- increased the speed of the assorted READLNS by a factor of 9 to 12
-
- times. Basically all these routines do is load a one dimension
-
- array of characters straight off the disk, and then go through the
-
- array sending off a line of text everytime it finds a Return or
-
- the end of the file.
-
-
- The Next_Word routine takes a list of parameters including a
-
- starting position and a starting condition and returns the next
-
- word in a text line. Basically anything that Pascal accepts as a
-
- word, this routine will return. It's also smart enough so that it
-
- will skip over words that are enclosed by comments or single
-
- quotes. If if finds a comment that doesn't end on that line, it
-
- returns a null word to the calling routine and lets the calling
-
- routine know what kind of comment or literal caused the exit.
-
-
- In_List takes a word parameter and performs a binary search
-
- through the List array looking for it. For those of you who
-
- aren't familiar with a binary search, it's similar to the game
-
- "Twenty Questions." It first looks in the middle of the list to
-
- see if that word is greater than, less than or equal to the word
-
- we're looking for. If it's greater than the word we're looking
-
- for, it looks in the middle of the lower half, If it's less than
-
- than the word we're looking for, it looks in the middle of the
-
- upper half. It continues doing this until it finds the word or
-
- determines that it isn't in the list at all.
-
-
- The Is_Cancel function simply determines if the user is
-
- holding down the Control C key down when the function is called.
-
- This is being used so the you can abort out of a routine if you
-
- want to.
-
-
- Advance_File_Pointer goes through an already opened file
-
- looking for a certain line number or routine name. When it finds
-
- it, it returns that text line and the line number to the calling
-
- routine. This is called from the List and Show routines.
-
-
-
- Init
-
- This routine is located in the module section. All it does
-
- is set up all the dialog and alert boxes, load the data file, and
-
- show the title screen. Most of the dialog box routines were
-
- copied and modified from one dialog box routine I stole from
-
- another one of my programs.
-
-
- Format
-
- OK, I know this is the one routine that you all want to know
-
- how it works. Get ready then. First it sets up all the relevant
-
- variables in Format_Init. It then calls Format_Stats which goes
-
- through the assorted dialog and alert boxes to get the users
-
- preferences for the program format. It might interest you that
-
- the two Returns dialog boxes are the same dialog box with the text
-
- changed. This is detailed in the Get_Returns routine.
-
-
- The program then opens up three files, the input file, the
-
- output file, and an error file. It then goes into a WHILE NOT EOF
-
- loop to get and process each of the lines in the input file.
-
-
- After it gets the line it passes the line to Fix_Line and
-
- then to Key_Words. Fix_Line is the first pass of the formatter
-
- for each line. It's first job is to strip all of the extra spaces
-
- from the line (Leading, trailing and inside the line.) It also
-
- adds a Return and a Line Feed after each "Live" semicolon. (One
-
- that's not in a literal or a comment.) It also adds spaces
-
- between certain characters to "Prettify" the line. And lastly, on
-
- it's way out of Fix_Line, it checks to see if the line ends as a
-
- comment or literal. If it is, then it adds another Return and a
-
- Line Feed at the end of the line. If the line ends as an
-
- unfinished comment, it tacks on a closing comment before the
-
- Return and an open comment after the Return.
-
-
- Key_Words is where most of the Returns are added, and the
-
- capitalization is fixed. It takes the line and goes through it
-
- using the Next_Word procedure. Everytime it gets a word the
-
- routine does two things. First it checks if it's a special word
-
- that might need a Return. If it is, then it adds a Return before
-
- or after it, according to the program's and the user's rules. It
-
- then calls Change_Word where the word has it's capitalization set
-
- according to the rules in the Caps array.
-
-
- Then if the length of that line and the line in Prior_Line
-
- are less than 255 it will hit the second half of the formatter.
-
- What happens now is that Prior_Line and the current line are
-
- concatenated together. It then goes through Prior_Line extracting
-
- each line that is terminated by a Return. (This may leave some
-
- characters in Prior_Line when we leave this section. They'll just
-
- get put onto the start of the next line.) As each line is
-
- extracted, it gets passed to the Add_Tabs routine.
-
-
- The Add_Tabs routine takes each line and adds the leading
-
- blanks to it. While it's doing this, it scans the line to see if
-
- there are any tabbing modifier words in it. (BEGIN, END, REPEAT,
-
- CASE, etc.) If it finds a word that would cause the tabbing to be
-
- increased (BEGIN, CASE, DO, etc.) it adds the blanks to the line
-
- and then adds that word to the tab stack (Tabbing). If it finds a
-
- word that would cause the tabbing to be decreased (END, UNTIL,
-
- BIOS, etc.) takes that word from the tab stack and then it adds
-
- the blanks to the line.
-
-
- When it's all done with that, it goes back to the top of the
-
- loop and does the whole cycle again.
-
-
-
-
- Cross Reference
-
-
- There were several general problems in writing this routine.
-
- the worst of them was that Pascal is a routine and level oriented
-
- language. That is, every new or nested procedure creates a new
-
- list of identifiers that will be ignored when the procedure is
-
- done being executed. And each nested routine can use all of the
-
- identifiers declared before it.
-
-
- So I had to figure out how to store and then forget each of
-
- these identifiers when I was done using them. I finally wound up
-
- implementing an array to hold all of the global words, and then a
-
- two dimensional array to hold all of the identifiers from each
-
- routine. Whenever the program hits the final end in a routine,
-
- the program then resets the number of words know for that routine
-
- to zero, and then decrements the level counter by one. Whenever a
-
- new routine is declared, it increments the level counter by one,
-
- and stores each of the identifiers into that level of the
-
- identifier array.
-
-
- The Add_to_Tree routine takes the word and it's line number
-
- and adds it to the binary tree. If it's a new word it calls
-
- Make_Node. If it's a word that is already in the tree, it calls
-
- Make_List_Node and adds it to the end of the linked list for that
-
- word. I'm using a set of linked list connected to a binary tree
-
- mainly to save space. If I wasn't doing it this way, the memory
-
- requirements become horrendous. (I know, I did it that way first,
-
- but kept blowing the stack from recursion when I used it on this
-
- program.)
-
-
- The Make_Node routine creates a new node for the binary tree.
-
- In doing so it calls Make_List_Node which creates the first node
-
- for the linked list that is attached to each node in the tree.
-
-
- The Write_Tree procedure goes through the binary tree the
-
- program has constructed doing an in-order traversal of each node.
-
- At each node, it prints out the contents of the attached list
-
- going from the First_Node to the Last_Node.
-
-
- Everytime a new declaration occurs, or six line numbers have
-
- been printed, the routine prints a carriage return to move down to
-
- the next line. I could have just kept printing out the line
-
- numbers, but this way the resulting printout looks much nicer.
-
-
- Lines
-
- This is just another interpretation of a line number printer.
-
- It looks for the starting position in the file (With
-
- Advance_File_Pointer) and the prints out each line with the
-
- corresponding line number. Before it prints each line it checks
-
- the line for a Form Feed character. If it finds one, it advances
-
- the page, prints a new page header, and clears the Form Feed
-
- character from the line. Also, as it prints each line, it checks
-
- each line with Should_It_Be_Off to see if that line is the final
-
- line to be printed.
-
- Show
-
- This routine was added after someone suggested that it might
-
- be handy to be able to look through a file to determine a starting
-
- point(s) for a listing or a cross referencing of a file.
-
- Basically it's similar to print routine except that it uses a
-
- Draw_String to put it on the screen.
-
-
- Since the program is designed for program code, I didn't have
-
- to worry about lines longer that 160 columns. Instead, the
-
- Put_It_On_The_Screen routine just breaks the line at column 76 and
-
- draws the remainder below it. It doesn't worry about word
-
- wrapping since that would alter the number of blanks in a line.
-
- (Not a good thing when the number of blanks in a line is
-
- important.)
-
-
- Procedure I/O
-
- This routine was initially suggested by one of the people in
-
- the BIX Atari.ST/Pascal conference. It goes through the file
-
- looking for the words PROGRAM, PROCEDURE, and FUNCTION. When it
-
- finds one of these words, It then checks to see if the line has
-
- an Open Parenthesis character. If it doesn't find one, it prints
-
- out that line. (No parameter list is there.) If it does find an
-
- Open Parenthesis, it prints out that line and every following line
-
- until it finds a Close Parenthesis character.
-
-
- If All_Declarations is set to TRUE, then it keeps reading and
-
- printing lines until it finds the word BEGIN on a line. At that
-
- point, it stops printing the lines and resumes the search for
-
- routine declarations.
-
-
- Do_Caps
-
- This was one of the easier routines for me to write. It's
-
- just a butchered version of the Do_Format routine that includes
-
- only the areas needed to change the word capitalization in a file.
-
-
- Word_Find
-
- This is another of the routines that I added after I had
-
- written most of the support routines for it already. I decided
-
- that since I already had the Next_Word routine written, I could
-
- use it to search through a file for any particular word and it's
-
- line number.
-
-
- This routine just goes through a text file line by line
-
- (Using F_Readln of course.) As it reads in each line, it uses
-
- next word to see if the line contains the word we're looking for.
-
- If it finds it, it writes the line number of the current line to
-
- the output file. It then proceeds to look through the rest of the
-
- line and print out any remaining occurances of the word on that
-
- line. It then moves on to the next line. This one took about 45
-
- minutes to get running. (And I don't know how many hours to add
-
- error checking, output formatting, etc.)
-
-
- Main_Menu
-
- The Main_Menu routine is where everything else gets called
-
- from. Basically it's just a simple dialog box with buttons. When
-
- a button is pressed, the routine then calls the proper routine.
-
- When control is returned back to this routine, it clears the
-
- screen and calls the dialog again.
-
-
- Finis
-
-
- Well that about wraps it up. This program has taken up too
-
- much of my time in the last year. But by having it around it's
-
- made writing my other programs that much easier (and then some!)
-
- Now that you have it, you can use it's advantages for your
-
- programs. It may not be as important to writing programs as a
-
- good compiler, but it comes in tied for second with a good editor.
-
-
- Appendix
-
-
- List of E_Format Defaults
- ====================================================
-
- Returns
- -------------------------------
- Return after const/var/type. Yes.
- Return after comma. No.
- Return before comma. No.
- Return before and. Yes.
- Return before or. Yes.
-
- Preserve comma-return. Yes.
- Strip blank lines. No.
- Preserve Math Returns. Yes.
- Add Return before BEGIN. Yes.
- Add FF before procedures. No.
-
- Capitalization
- -------------------------------
- Pascal Reserved - Upper Case.
- Pascal Constants - Upper Case.
- Pascal Types - Upper Case.
- Pascal routines - Upper Case.
-
- GEM Const - Upper Case.
- Gem Type - Upper Case.
- Gem Routines - Upper Case.
-
- Your words - Lower Case.
-
- Tabbing
- -------------------------------
-
- Tab after begin/procedure: 3.
- Tab before BEGIN: 1.
- Tab after Record: 3.
- Tab after DO: 3.
- Tab before then/else: 2.
- Tab after CONST/etc: 3.
- Tab before AND/OR: 2.
- Tab after case () of: 3.
- Tab for Nested Procedure: 3.
-
- Appendix 2
-
- Dictionary for EPASUTIL.DAT word list.
-
- 1= Pascal Reserved words.
- 2= Pascal Constants.
- 3= Pascal Types.
- 4= Pascal Routines.
- 5= GEM Constants.
- 6= GEM Types.
- 7= GEM Routines.
- 8= Programmer defined words.
-
-
-
-